package net.entelijan.cobean.examples.showcase.bind.text;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JOptionPane;

import net.entelijan.cobean.bind.impl.BoundPropBinding;
import net.entelijan.cobean.core.ICobean;
import net.entelijan.cobean.data.literature.ILitService;
import net.entelijan.cobean.data.literature.LitAuthor;
import net.entelijan.cobean.data.literature.LitBook;
import net.entelijan.cobean.examples.util.ExamplesUtil;
import net.entelijan.cobean.examples.util.RoundaboutIterator;
import net.entelijan.cobean.text.DefaultTextInitializer;
import net.entelijan.cobean.text.converter.DateTextConverter;
import net.entelijan.cobean.text.converter.IntTextConverter;
import net.entelijan.cobean.text.converter.LongTextConverter;
import net.entelijan.scf.IShowcase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PathBindShowcase implements IShowcase<PathBindPanel> {

	private static Log log = LogFactory.getLog(PathBindShowcase.class);

	private ILitService service = null;

	private PathBindModel model = new PathBindModel();

	public PathBindShowcase() {
		super();
	}

	@Override
	public void init(final PathBindPanel view) {
		{
			DefaultTextInitializer<String> ini = new DefaultTextInitializer<String>();
			ini.setCoTextComponent(view.getAuthorNameTextField());
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<String> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.author.name");
			model = binding.bind(model, cobean);
		}
		{
			DefaultTextInitializer<Date> ini = new DefaultTextInitializer<Date>();
			ini.setCoTextComponent(view.getAuthorBirthdayTextField());
			ini.setConverter(new DateTextConverter("dd.MM.yyyy"));
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<Date> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.author.birthday");
			model = binding.bind(model, cobean);
		}
		{
			DefaultTextInitializer<Long> ini = new DefaultTextInitializer<Long>();
			ini.setCoTextComponent(view.getAuthorIdTextField());
			ini.setConverter(new LongTextConverter());
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<Long> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.author.id");
			model = binding.bind(model, cobean);
		}
		{
			DefaultTextInitializer<String> ini = new DefaultTextInitializer<String>();
			ini.setCoTextComponent(view.getBookTitleTextField());
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<String> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.title");
			model = binding.bind(model, cobean);
		}
		{
			DefaultTextInitializer<Long> ini = new DefaultTextInitializer<Long>();
			ini.setCoTextComponent(view.getBookIDTextField());
			ini.setConverter(new LongTextConverter());
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<Long> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.id");
			model = binding.bind(model, cobean);
		}
		{
			DefaultTextInitializer<String> ini = new DefaultTextInitializer<String>();
			ini.setCoTextComponent(view.getBookSubtitleTextField());
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<String> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.subtitle");
			model = binding.bind(model, cobean);
		}
		{
			DefaultTextInitializer<Integer> ini = new DefaultTextInitializer<Integer>();
			ini.setConverter(new IntTextConverter());
			ini.setCoTextComponent(view.getBookYearTextField());
			ini.setCoFailureComponent(view.getFailureTextField());
			ICobean<Integer> cobean = ini.initialize();

			BoundPropBinding binding = new BoundPropBinding();
			binding.setCompProperty("value");
			binding.setModelPath("book.year");
			model = binding.bind(model, cobean);
		}

		// Create a dummy author to be set into books
		final LitAuthor dummyAuthor = new LitAuthor();
		dummyAuthor.setBirthday(ExamplesUtil.createDate("yyyy.MM.dd",
				"1911.11.11"));
		dummyAuthor.setId(123456);
		dummyAuthor.setName("Dummy Dummy");

		final RoundaboutIterator<LitBook> books = new RoundaboutIterator<LitBook>(
				getOneBookPerAuthor());

		this.model.setBook(books.next());

		view.getShowBooksButton().addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(view, ExamplesUtil.listToString(
						books.getContent(), 130));
			}

		});
		view.getNextBookButton().addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				LitBook book = books.next();
				log.info("[actionPerformed] " + book);
				model.setBook(book);
			}

		});
		view.getPreviousBookButton().addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				LitBook book = books.previus();
				log.info("[actionPerformed] " + book);
				model.setBook(book);
			}

		});

		view.getSetDummyAuthorButton().addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				model.getBook().setAuthor(dummyAuthor);
			}

		});
	}

	/**
	 * Returns a list of books with distinct authors.
	 */
	private List<LitBook> getOneBookPerAuthor() {
		ArrayList<LitBook> re = new ArrayList<LitBook>();
		for (LitAuthor a : service.loadAllAuthors()) {
			List<LitBook> books = a.getBooks();
			if (books != null && books.size() > 0) {
				re.add(books.get(0));
			}
		}
		return re;
	}

	public ILitService getService() {
		return service;
	}

	public void setService(ILitService service) {
		this.service = service;
	}

	public PathBindModel getModel() {
		return model;
	}

	public void setModel(PathBindModel model) {
		this.model = model;
	}

}
